#include <my_header.h>
// 服务端 即时通信 接收一个客户端
// 重启timewait!!
/* Usage: ./2_server_select_reset */
int main(void){                                  
    // 服务端IP地址和端口
    char *ip = "192.168.229.128";
    char *port = "8080";

    // socket文件描述符
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(socket_fd, -1, "socket");

    //使用setsockopt函数，修改socket行为
    // 如下: 要求如果某个端口处于time_wait状态, 允许重新使用
    int reuse = 1;
    //setsockopt(套接字文件描述符，)
    //`setsockopt 函数`需要在`bind函数`之前执行,  socket函数之后
    int res_setsocktopt = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    ERROR_CHECK(res_setsocktopt, -1, "setsockopt");

    // 构建"struct sockaddr"类型
    struct sockaddr_in sockaddr;
    sockaddr.sin_family = AF_INET;  //ipv4
    sockaddr.sin_port = htons(atoi(port));
    sockaddr.sin_addr.s_addr = inet_addr(ip);

    // 绑定地址
    int ret_bind = bind(socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
    ERROR_CHECK(ret_bind, -1, "bind");

    // 监听
    int res_lis = listen(socket_fd, 10);
    ERROR_CHECK(res_lis, -1, "listen");

    // 获取连接
    int net_fd = accept(socket_fd, NULL, NULL);
    ERROR_CHECK(net_fd, -1, "accept");

    fd_set set; // 定义监听集合
    while(1)
    {
        FD_ZERO(&set);
        FD_SET(STDIN_FILENO, &set);
        FD_SET(net_fd, &set);
        
        // 使用select监听集合
        int res_select = select(net_fd+1, &set, NULL, NULL, NULL);
        ERROR_CHECK(res_select, -1, "select");

        if(FD_ISSET(STDIN_FILENO, &set))
        {
            //读取标准输入
            char buf[60] = {0};
            read(STDIN_FILENO, buf, sizeof(buf)-1);
            send(net_fd, buf, sizeof(buf), 0);
        }
        if(FD_ISSET(net_fd, &set))
        {
            // 读取网络数据->打印
            char buf[60] = {0};
            ssize_t ret_recv = recv(net_fd, buf, sizeof(buf), 0);
            if(ret_recv == 0)
            {
                net_fd = accept(socket_fd, NULL, NULL);
                continue;
            }
            printf("client message :%s\n", buf);
        }
    }
    close(socket_fd);
    close(net_fd);
    return 0;
}


